package protocol

import (
	"bytes"
	"encoding/binary"
	"github.com/spf13/cast"
	"learn/zinxLearn/pkg/zinx/ziface"
	"learn/zinxLearn/pkg/zinx/znet"
)

const (
	headers = "headers"
)

type DataPack struct{}

func NewDataPack() *DataPack {
	return &DataPack{}
}
func (d *DataPack) GetHeadLen() uint32 {
	// headers(7)+Id uint32(4字节) +  DataLen uint32(4字节)
	return 7 + 8
}
func (d *DataPack) intToByte(msg ziface.IMessage) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{})
	if err := binary.Write(buf, binary.BigEndian, msg.GetMsgID()); err != nil {
		return nil, err
	}
	if err := binary.Write(buf, binary.BigEndian, msg.GetDataLen()); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
func (d *DataPack) byteToInt(b []byte) (x uint32) {
	buf := bytes.NewBuffer(b)
	binary.Read(buf, binary.BigEndian, &x)
	return
}
func (d *DataPack) EnPack(msg ziface.IMessage) ([]byte, error) {
	var res []byte
	num, err := d.intToByte(msg)
	if err != nil {
		return nil, err
	}
	res = append(append([]byte(headers), num...), msg.GetData()...)
	return res, nil
}
func (d *DataPack) DePack(nums []byte, write chan<- ziface.IMessage) []byte {
	var (
		i uint32
		l = cast.ToUint32(len(nums))
	)
	for i < l {
		if i+d.GetHeadLen() > l { // 没有完整的头部
			break
		}
		msg := &znet.Message{}
		if string(nums[i:i+7]) == headers { // 符合标志
			msg.SetMsgID(d.byteToInt(nums[i+7 : i+7+4]))
			msg.SetDataLen(d.byteToInt(nums[i+7+4 : i+7+8]))
			if (msg.GetDataLen() + i + d.GetHeadLen()) > l { // 数据是否完整
				break
			}
			msg.SetData(nums[i+d.GetHeadLen() : msg.GetDataLen()+i+d.GetHeadLen()])
			write <- msg
			i += msg.GetDataLen() + d.GetHeadLen()
		}
	}
	if i == l {
		return nil
	}
	return nums[i:] // 返回未处理的部分
}
